package game.util;

import game.Game;

import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;

import shared.Message;
import shared.io.messages.ErrorMessage;
import shared.io.messages.PlayerMessage;

public class ChatModule extends Object {

   /**
    * Height of a text row in pixels.
    */
   private final int ROW_HEIGHT = 27;
   /**
    * Length of a single message display in milliseconds.
    */
   private final int MESSAGE_DISPLAY_TIME = 4000;
   /**
    * Map of messages and the time they were posted.
    */
   private Map<Long, Message> messageMap;
   private Game game;
   private Date date;
   /**
    * BufferGraphics, holds the data of the image.
    */
   private Graphics bufferGraphics;
   /**
    * Used to reuse the image instead of creating it every refresh.
    */
   private Image bufferImage;
   
   public ChatModule(Game game) {
      this.game = game;
      date = new Date();
      messageMap = new TreeMap<Long, Message>();
      try {
         bufferImage = new Image(500, 500);
         bufferGraphics = new Graphics();
         bufferGraphics = bufferImage.getGraphics();
      } catch (SlickException e) {
         
      }
   }

   /**
    * Renders the chat.
    */
   public void render(GameContainer container, Graphics g, int x, int y) {
      g.drawImage(bufferImage, x, y);
   }

   /**
    * Update checks if new messages have arrives and if old have expired.
    */
   public void update() {
      date = new Date();
      Message msg;
      if ((msg = game.getMessage()) != null) {
         messageMap.put(date.getTime(), msg);
      }
      Iterator<Entry<Long, Message>> it = messageMap.entrySet().iterator();
      long now = date.getTime();
      
      int i = 0;
      while (it.hasNext()) {
         Entry<Long, Message> entry = it.next();
         if (entry.getKey() + MESSAGE_DISPLAY_TIME < now) {
            it.remove();
         }
      }
      bufferGraphics.clear();
      
      it = messageMap.entrySet().iterator();
      while (it.hasNext()) {
         int y = messageMap.size() * ROW_HEIGHT - i * ROW_HEIGHT;
         Entry<Long, Message> entry = it.next();
         if (entry.getValue() instanceof PlayerMessage) {
            bufferGraphics.setColor(Color.white);
            PlayerMessage pmsg = (PlayerMessage) entry.getValue();
            bufferGraphics.drawImage(TileGraphics.gfx().getCharPortraits()[pmsg.getSender().getPlayerColor()], 0, y);
            bufferGraphics.drawString(pmsg.getSender().getName() + ": " + pmsg.getMessage(), 30, y + 4);
         } else if (entry.getValue() instanceof ErrorMessage) {
            bufferGraphics.setColor(Color.red);
            bufferGraphics.drawString("WARNING: " + entry.getValue().getMessage(), 30, y + 4);
         } else {
            bufferGraphics.setColor(Color.cyan);
            bufferGraphics.drawString(entry.getValue().getMessage(), 30, y + 4);
         }
         i++;
      }
      bufferGraphics.flush();
   }
}
